﻿using org.xisoft.game.utils.game;
using org.xisoft.game.utils.game.algorithms;
using System;
using System.Collections.Generic;

namespace ReversiModule.Chess.Algorithms
{
    class AiAlgorithm : AlphaBetaAlgorithm<ReversiBoard>
    {
        public AiAlgorithm()
        {
            MaxDeep = 4;
        }

        public bool CanMoves(ReversiBoard board)
        {
            List<MoveAction> list = new List<MoveAction>();
            int score;
            for (int i = 0; i < board.MaxX; i++)
                for (int j = 0; j < board.MaxY; j++)
                {
                    score = GetScore(board, i, j);
                    if (score > 0)
                        return true;
                }
            return false;

        }


        public override List<MoveAction> GetAllCanMoves(ReversiBoard board)
        {
            List<MoveAction> list = new List<MoveAction>();
            int score;
            for (int i = 0; i < board.MaxX; i++)
                for (int j = 0; j < board.MaxY; j++)
                {
                    score = GetScore(board as ReversiBoard, i, j);
                    if (score > 0)
                        list.Add(new MoveAction { ToX = i, ToY = j, Score = score });
                }
            return list;

        }



        public int GetScore(ReversiBoard board, int x, int y)
        {
            int score = 0;
            if (board[x, y] != null)
                return 0;
 

            /**
             * 少计算了斜着的
             */
            //score += GetLeftCount(x, y, isCurrentBlack) * hMultiple;
            //score += GetRightCount(x, y, isCurrentBlack) * hMultiple; 
            //score += GetUpCount(x, y, isCurrentBlack) * vMultiple; 
            //score += GetDownCount(x, y, isCurrentBlack) * vMultiple;

            int tmpScore;
            for (int dx = -1; dx < 2; dx++)
                for (int dy = -1; dy < 2; dy++)
                {
                    if (dx == 0 && dy == 0) continue;
                    tmpScore = board.GetLinkCount(board,x, y, dx, dy);

                    score += tmpScore;
                }

            /**
 分数计算，这里计算不准确
 应该像是这样的
 int weight[6][6] = {   
{36, 0, 16, 16, 0, 36},   
{0,  0, 1,  1,  0, 0},   
{16, 1, 2,  2,  1, 16},   
{16, 1, 2,  2,  1, 16},   
{0,  0, 1,  1,  0, 0},   
{36, 0, 16, 16, 0, 36},   
};   

  */



            if (score > 0)
            {
                if ((x == 1 || x == board.MaxX-2) && (y <= 1 || y >= board.MaxY - 2))
                    return 1;
                if ((x == 0 || x == board.MaxX - 1) && (y == 1 || y == board.MaxY - 2))
                    return 1;



                if ((x == 0 || x == board.MaxX - 1) && (y == 0 || y == board.MaxY - 1))
                    return board.MaxX * board.MaxY;

                if (x == 0 || x == board.MaxX - 1 || y == 0 || y == board.MaxY - 1)
                    return score + board.MaxX + board.MaxY;
            }
            return score ;
        }

        public override bool CanMove(ReversiBoard board, int x, int y)
        {
            if (!base.CanMove(board,x, y) )
                return false;

            ReversiBoard reversiBoard = board as ReversiBoard;
            for (int i = -1; i < 2; i++)
                for (int j = -1; j < 2; j++)
                {
                    if (i == 0 && j == 0) continue;

                    if (reversiBoard.GetLinkCount(board,x, y, i, j) > 0)
                        return true;
                }

            return false;
        }



        public override bool? GetWinColor(ReversiBoard chessBoard)
        {
            if(GetAllCanMoves(chessBoard).Count>=0)return null;

            int blackCount = 0;
            int redCount = 0;
            for (int i = 0; i < ReversiBoard.MAXX; i++)
                for (int j = 0; j < ReversiBoard.MAXY; j++)
                {
                    ChessItem item = chessBoard[i, j];
                    if (item == null) continue;
                    if (item.IsBlack)
                        blackCount++;
                    else
                        redCount++;
                }
            return blackCount > redCount;
        }
    }
}
